package ui;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import remote.Connection;
import server.IServerFacade;
import server.IServerSession;

import infrastructure.exceptions.LoginException;
import infrastructure.exceptions.NetworkException;
import inftrastructure.exceptions.ClientRuntimeException;

import core.ServerFacade;



public class LogonDialog extends JDialog implements ActionListener,Runnable{

	// Data members definition
	private char[] password;
	private String username;
	private String hostname;
	private int port;
	private ServerFacade facade = null;
	private Connection con = null;
	private boolean loginfailed = false;
	private AnimalsAdoptionClient currClient = null;
	private IServerSession currSession = null;
	private boolean portOK = true;
	
	// Components Definition
	private JTextField useridField = new JTextField(10);
	private JLabel usernameLabel = new JLabel ("User ID:");
	private JTextField hosttxtField = new JTextField(15);
	private JLabel hostLabel = new JLabel ("Server:");
	private JTextField portTxtField = new JTextField(5);
	private JLabel portLabel = new JLabel ("TCP Port");
	private JPasswordField passwordField = new JPasswordField(10);
	private JLabel passwordLabel = new JLabel ("Password:");
	private JButton loginButton = new JButton ("Login");
	private JButton cancelButton = new JButton ("Cancel");
	
	private JPanel dialogPanel = new JPanel(new GridLayout (2,2));
	private JPanel buttonPanel = new JPanel(new FlowLayout());
	private JPanel registerPanel = new JPanel(new GridLayout (2,2));
	private JPanel mainPanel = new JPanel(new BorderLayout());
	
	// Constructor Definition
	public LogonDialog (AnimalsAdoptionClient client)
	{
		// Set reference to client program
		currClient = client;
		
		// Set fields and label characteristics
		useridField.setFont(new Font("DialogInput", Font.PLAIN, 12));
		hosttxtField.setFont(new Font("DialogInput", Font.PLAIN, 12));
		portTxtField.setFont(new Font("Serif", Font.ITALIC, 16));
		usernameLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
		passwordLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
		hostLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
		hostLabel.setLabelFor(hosttxtField);
		usernameLabel.setLabelFor(useridField);
		passwordLabel.setLabelFor(passwordField);
		portLabel.setLabelFor(portTxtField);
		
		useridField.setToolTipText("Enter your User Name");
		passwordField.setToolTipText("Enter your Password");
		hosttxtField.setToolTipText("Enter Host name - \nas a server name or an IP Address");

		
		// Set server's default HostName as localhost and port
		 // - This version it's a fix port
		hosttxtField.setText("localhost");
		portTxtField.setText("1777");
		portTxtField.setEditable(false);
		
		// Set the border for registration panel
		registerPanel.setBorder(
				BorderFactory.createCompoundBorder(
					BorderFactory.createCompoundBorder(
						BorderFactory.createTitledBorder("Client Registration"),
						BorderFactory.createEmptyBorder(5,5,5,5)),
						registerPanel.getBorder()));
		
		// Add components to the proper containers in GridLayout format
		dialogPanel.add(usernameLabel);
		dialogPanel.add(useridField);
		dialogPanel.add(passwordLabel);
		dialogPanel.add(passwordField);
		registerPanel.add(hostLabel);
		registerPanel.add(hosttxtField);
		registerPanel.add(portLabel);
		registerPanel.add(portTxtField);
		buttonPanel.add(loginButton);
		buttonPanel.add(cancelButton);
		mainPanel.add(dialogPanel, BorderLayout.CENTER);
		mainPanel.add(registerPanel, BorderLayout.SOUTH);
		getContentPane().add(mainPanel, BorderLayout.CENTER);
		getContentPane().add(buttonPanel, BorderLayout.SOUTH);
				
		// Set the proper ActionListner for each component
		passwordField.addActionListener(this);
		useridField.addActionListener(this);
		hosttxtField.addActionListener(this);
		loginButton.addActionListener(this);
		cancelButton.addActionListener(this);

		// Initialize frame properties
		setModal(true);
		setSize(250,150);
		setResizable(false);
		setLocation(400, 300);
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		pack();
		addWindowListener(new WindowAdapter(){
			public void windowClosing (WindowEvent e){
				System.exit(0);
				}
			}
		);	
	}
	
	public void run()
	{
		// Display GUI
		setVisible(true);
	}
	
	
	public void actionPerformed(ActionEvent e)
	{
		String pass = null;
		
		if (e.getSource() == cancelButton)
		{
			System.out.println("Debug - in cancel button");
			
			// Cancel Button was pressed
			dispose();
			System.exit(0);
		}
		else // when or OK button enter were pressed  
		{
			// Check if the user entered a User Name
			if (useridField.getText() == null || (useridField.getText().equals("")))
			{
				JOptionPane.showMessageDialog(null, "Please enter your user name",
						"Warning", JOptionPane.WARNING_MESSAGE);
			}
			// Check if the hostname is not empty
			else if (hosttxtField.getText() == null || hosttxtField.getText().equals("")) 
			{
				JOptionPane.showMessageDialog(null, "Please enter Host name or address",
						"Warning", JOptionPane.WARNING_MESSAGE);
			}
			else
			{
				username = useridField.getText();
				password = passwordField.getPassword();	
				if (password == null )
				{
					// Set empty password
					System.out.println("Debug -  THE PASSWORD WAS EMPTY");
					pass = new String("");
				}
				else
				{
					pass = new String(password);
				}

				hostname = hosttxtField.getText();
				try
				{
					// Check TPC ort is a number
					portOK = true;
					port = Integer.parseInt(portTxtField.getText());
				}
				catch (NumberFormatException ex)
				{
					JOptionPane.showMessageDialog(null, "TCP port must be a number",
							"Warning", JOptionPane.WARNING_MESSAGE);
					portOK = false;
					
				}
				if (portOK)
				{
					try
					{
						loginfailed = false;
						
						// Connect to server
						con = Connection.getConnection(hostname, port);
						facade = new ServerFacade(con);
						
						try
						{	
							// Try to login with the provided credentials
							currSession = facade.logon(username,pass);	
						}
						catch(LoginException ex)
						{
							loginfailed = true;
							
							// User name and/or Password where wrong
							JOptionPane.showMessageDialog(null, "Login Failed!\nBad Username or Password",
									"Error", JOptionPane.ERROR_MESSAGE);	
							passwordField.setText(null);
						}
						catch(Exception ex)
						{
							throw new ClientRuntimeException(ex.getMessage(), ex);
						}
						if (!loginfailed)
						{
							// Set Login returned parameters in AnimalAdoptionClient
							currClient.facade = facade;
							currClient.conn = con;
							currClient.session = currSession;
							dispose();
						}
						else
						{
							loginfailed = false;
						}
						
					}
					catch(NetworkException ex)
					{
						loginfailed = true;
						JOptionPane.showMessageDialog(null, "Error Connecting to server",
								"Error", JOptionPane.ERROR_MESSAGE);
						
						// Clear hostname text field
						hosttxtField.setText(null);
					}
					
				}
			}
		}
	}
}
